package com.songtech.uitest.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;

/**
 * 写此类的目的用于将项目打包成jar文件并运行时，会遇到访问包内资源路径不正确的问题。
 * 需要用这样的写法才能访问到
 * 参考：https://blog.csdn.net/dunceiam/article/details/42740537
 */
@Component
public class JarPathHelper {

    private Logger logger = LoggerFactory.getLogger(JarPathHelper.class);

    @Autowired
    private Space space;

    /**
     * 获取jar所在外部目录的路径，支持中文路径
     * @param fileName 文件名
     * @return jar所在外部目录的路径+文件名
     */
    public String getJarPath(String fileName){
        //这一句，若在idea里会得到/target/classes/文件名，若在jar里，会得到真实路径+jar包名/文件名(但这个路径不通用)
        String path = JarPathHelper.class.getProtectionDomain().getCodeSource().getLocation().getFile() + fileName;
        try {
            path = java.net.URLDecoder.decode(path, "UTF-8"); //修复中文路径问题
        } catch (UnsupportedEncodingException e) {
            logger.error("获取" + fileName + "文件路径失败，访问路径为：" + path);
            logger.error("异常信息如下：" + e.toString());
        }
        //修复不通用路径问题
        path = new File(path).getParentFile().getAbsolutePath() + "\\" + fileName;
        logger.info("获取" + fileName + "文件路径成功，路径为：" + path);

        return path;
    }

    /**
     * 取得浏览器驱动文件完整正确路径，不论项目是在idea中，还是在jar包中的情况
     * @param fileName 浏览器驱动文件名
     * @return 在idea中返回target/classes/文件名，在jar包中返回和jar包同在的 外部目录/文件名
     */
    public String getWebDriverFilePath(String fileName){
        //这一句，若在idea里会得到/target/classes/文件名，若在jar里，会得到真实路径+jar包名/文件名(但这个路径不通用)
        String path = JarPathHelper.class.getProtectionDomain().getCodeSource().getLocation().getFile() + fileName;
        if(path.contains(".jar")) { //若项目在jar包里的情况
            path = getJarPath(fileName);
        }
        logger.info("得到" + fileName + "的文件路径为：" + path);

        return path;
    }



    /**
     * 得到资源文件完整正确路径，不论项目是在idea中，还是在jar包中的情况。支持中文路径
     * @param fileName 资源文件名
     * @return 在idea中返回target/classes路径+文件名，在jar包中返回jar包内根目录+文件名。
     */
    public String getResourceFilePath(String fileName){
        //这一句，若在idea里会得到/target/classes/文件名，若在jar里，会得到真实路径+jar包名/文件名(但这个路径不通用)
        String path = JarPathHelper.class.getProtectionDomain().getCodeSource().getLocation().getFile() + fileName;
        if(path.contains(".jar")) { //若项目在jar包里的情况
            URL url = JarPathHelper.class.getResource("/" + fileName);
            path = url.toString();
        }
        logger.info("得到" + fileName + "的文件路径为：" + path);

        return path;

    }


    /**
     *
     * 取得或新建和jar包同目录的文件夹screenshots+文件名，目前用于存放截图文件
     * 若文件夹screenshots不存在，则新建。同样支持中文路径
     * @param fileName 截图文件名
     * @return jar包外同级screenshot文件夹路径+文件名
     */
    public String getOrNewFolderAtJarPath(String fileName){
        //得到jar path: .../abc.jar/
        String jarPath = JarPathHelper.class.getProtectionDomain().getCodeSource().getLocation().getFile();
        try {
            jarPath = java.net.URLDecoder.decode(jarPath, "UTF-8"); //修复中文路径问题
        } catch (UnsupportedEncodingException e) {
            logger.error(space.getSpace() + "获取jar包路径失败，访问路径为：" + jarPath);
            logger.error(space.getSpace() + "异常信息如下：" + e.toString());
        }
        //去掉abc.jar,加上screenshots;
        jarPath = new File(jarPath).getParentFile().getAbsolutePath() + "\\screenshots";

        //判断文件夹是否存在，不存在创建文件夹
        File file =new File(jarPath);
        if(!file.exists() || !file.isDirectory()){
            logger.info(space.getSpace() + "screenshots目录不存在。");
            file.mkdir();
            logger.info(space.getSpace() + "screenshots目录已创建。");
        }

        jarPath = jarPath + "\\" + fileName;

        logger.info(space.getSpace() + "得到" + fileName + "文件的存放路径为：" + jarPath);

        return jarPath;
    }



    /**
     * 取得截图文件夹完整正确路径，不论项目是在idea中，还是在jar包中的情况
     * @param fileName 截图文件名
     * @return 在idea中返回项目根目录/screenshot+文件名，在jar包中返回和jar包同在的外部目录/screenshot+文件名
     */
    public String getScreenShotsFilePath(String fileName){
        //这一句，若在idea里会得到/target/classes/，若在jar里，会得到真实路径+jar包名/(但这个路径不通用)
        String path = JarPathHelper.class.getProtectionDomain().getCodeSource().getLocation().getFile();
        if(path.contains(".jar")) { //若项目在jar包里的情况
            path = getOrNewFolderAtJarPath(fileName);
        }
        else{
            path = new File(path).getParentFile().getParentFile().getAbsolutePath() + "\\screenshots";
            //判断文件夹是否存在，不存在创建文件夹
            File file =new File(path);
            if(!file.exists() || !file.isDirectory()){
                logger.info(space.getSpace() + "screenshots目录不存在。");
                file.mkdir();
                logger.info(space.getSpace() + "screenshots目录已创建。");
            }
            path = path + "\\" + fileName;
        }
        logger.info(space.getSpace() + "得到截图文件的存放路径为：" + path);

        return path;
    }


    /**
     * 取得结果压缩文件完整正确路径，不论项目是在idea中，还是在jar包中的情况
     * @param fileName 待压缩文件(夹)名
     * @return 在idea中返回项目根目录/+文件名，在jar包中返回和jar包同在的外部目录/+文件名
     */
    public String getZipFilePath(String fileName) {
        //这一句，若在idea里会得到/target/classes/，若在jar里，会得到真实路径+jar包名/(但这个路径不通用)
        String path = JarPathHelper.class.getProtectionDomain().getCodeSource().getLocation().getFile();
        if(path.contains(".jar")) { //若项目在jar包里的情况
            try {
                path = java.net.URLDecoder.decode(path, "UTF-8"); //修复中文路径问题
            } catch (UnsupportedEncodingException e) {
                logger.error(space.getSpace() + "获取测试结果压缩文件路径失败，访问路径为：" + path);
                logger.error(space.getSpace() + "异常信息如下：" + e.toString());
            }
            //去掉abc.jar;
            path = new File(path).getParentFile().getAbsolutePath();
        }
        else{
            path = new File(path).getParentFile().getParentFile().getAbsolutePath();
        }
        path = path + "\\" + fileName;

        logger.info(space.getSpace() + "得到测试结果压缩文件的存放路径为：" + path);

        return path;

    }


    /**
     * 获取不论在idea工程的target/classes/下，或jar包的根目录中，文件的文件流
     * 目前用于读取testng.xml
     * @param fileName 资源文件名
     * @return 该文件的文件流
     */
    public InputStream getRootPathStreamInJar(String fileName){
        InputStream in = JarPathHelper.class.getResourceAsStream("/" + fileName);
        return in;
    }


    public static void main(String[] args){

        ApplicationContext context=new ClassPathXmlApplicationContext("classpath:spring-test-config.xml");

//        JarPathHelper helper = (JarPathHelper) SpringUtil.getBean("jarPathHelper");
        JarPathHelper helper = (JarPathHelper) context.getBean("jarPathHelper");
        helper.getWebDriverFilePath("geckodriver.exe");
        helper.getResourceFilePath("logback.xml");
        helper.getScreenShotsFilePath("截图文件.png");

    }









}
